<script setup lang="ts">
import { type MenuOption } from 'naive-ui'
import { RouterLink } from 'vue-router'
import { renderIcon } from '@/utils'
import { icons, type IconsType } from './menu-icons'

defineProps<{
  collapsed: boolean
  collapsedWidth: number
}>()

const { load, collection } = useMenu()
const router = useRouter()

await Promise.all([load()])

const menuOptions = computed(() =>
  collection.value?.data ? convertMenuData(collection.value.data) : [],
)

/**
 * 将后台返回的数据转换为 n-menu 所需的 options 格式
 */
const convertMenuData = (data: MenuModel[]) => {
  return data.map((item) => {
    const option: MenuOption = {
      label: item.label,
      icon: item.icon ? renderIcon(icons[item.icon as IconsType]) : undefined,
      key: item.router_name,
    }

    if (item.children && item.children.length > 0) {
      option.children = convertMenuData(item.children)
    } else {
      option.label = () =>
        h(
          RouterLink,
          {
            to: {
              name: item.router_name,
            },
          },
          { default: () => item.label },
        )
    }

    return option
  })
}

// 将菜单信息合并到路由的 meta 中
const mergeMenuToRoute = (menuData: MenuModel[]) => {
  const routes = router.getRoutes()
  menuData.forEach((menu) => {
    const route = routes.find((r) => r.name === menu.router_name)
    if (route) {
      route.meta = {
        ...route.meta,
        title: menu.label,
        icon: menu.icon,
      }
    }
    if (menu.children) {
      mergeMenuToRoute(menu.children)
    }
  })
}

// 监听菜单数据变化，更新路由 meta
watch(
  () => collection.value?.data,
  (newData) => {
    if (newData) {
      mergeMenuToRoute(newData)
    }
  },
  { immediate: true },
)
</script>

<template>
  <n-menu
    :collapsed-width="collapsedWidth"
    :options="menuOptions"
    :value="router.currentRoute.value.name as string"
  />
</template>
